//默认情况，智能指针过期时，编译器自动用 delete原始指针 释放资源。
//程序员也可以自定义删除器，改变智能指针释放资源的行为
//删除器可以是全局函数，仿函数和Lambda表达式，形参为原始指针


#include<memory>
#include<iostream>
#include<string>
#include<vector>
using namespace std;

class AA
{
public:
	AA()
	{
		cout << m_name << "调用构造函数AA()。" << endl;
	}
	
	AA(const string& name) :m_name(name)
	{
		cout << "调用构造函数AA(" << m_name << ") " << endl;	// "<<变量名<<"
	}
	
	~AA()
	{
		cout << "调用了析构函数~AA(" << m_name << ")" << endl;
	}
	string m_name;
	
};

void deletefunc(AA* a)
{
	cout << "自定义删除器， 全局函数。" << endl;
	delete a;
}

class deleteclass
{
public:
	void operator()(AA* a)
	{
		cout << "自定义删除器，仿函数。" << endl;
		delete a;
	}
};

auto deletelambda = [](AA* a)	//auto 为function<void(AA*)>
	{
		cout << "自定义删除器，Lambda" << endl;
		delete a;
	};

int main()
{	
    //删除器
	//shared_ptr<AA> pa1(new AA("张三"));   //没有指定删除器用，缺省的删除器（自动delete 原始指针）

	//shared_ptr
	shared_ptr<AA> pa2(new AA("李四"), deletefunc);	//普通全局函数删除器

	shared_ptr<AA> pa3(new AA("王五"), deleteclass());	//仿函数

	shared_ptr<AA> pa4(new AA("赵六"), deletelambda);		//lambda表达式

	shared_ptr<AA> pa5(new AA("孙七"), [](AA* a)		//也是lambda表达式
		{
			cout << "自定义删除器，Lambda" << endl;
			delete a;
		});


	//unique_ptr，略微麻烦一点
	unique_ptr<AA, decltype(deletefunc)*> pu1(new AA("张三"), deletefunc);	//模板参数类型用decltyoe推断会更方便
	unique_ptr<AA, void(*)(AA*)> pu1(new AA("张三"), deletefunc);	//直接用函数指针也可以
	unique_ptr<AA, deleteclass> pu2(new AA("李四"), deleteclass());

	unique_ptr<AA, decltype(deletelambda)> pu3(new AA("王五"), deletelambda);

	return 0;
}


